home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 1 (Walnut Creek)
/
Aminet - June 1993 [Walnut Creek].iso
/
aminet
/
mus
/
edit
/
amisox_wav.lha
/
vibro.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-03-27
|
3KB
|
136 lines
/*
* July 5, 1991
* Copyright 1991 Lance Norskog And Sundry Contributors
* This source code is freely redistributable and may be used for
* any purpose. This copyright notice must be maintained.
* Lance Norskog And Sundry Contributors are not responsible for
* the consequences of using this software.
*/
/*
* Sound Tools Vibro effect file.
*
* Modeled on world-famous Fender(TM) Amp Vibro knobs.
*
* Algorithm: generate a sine wave ranging from
* 0 + depth to 1.0, where signal goes from -1.0 to 1.0.
* Multiply signal with sine wave. I think.
*/
#include <math.h>
#include "st.h"
/* Private data for Vibro effect */
typedef struct vibrostuff {
float speed;
float depth;
short *sinetab; /* sine wave to apply */
int mult; /* multiplier */
unsigned length; /* length of table */
int counter; /* current counter */
} *vibro_t;
/*
* Process options
*/
vibro_getopts(effp, n, argv)
eff_t effp;
int n;
char **argv;
{
vibro_t vibro = (vibro_t) effp->priv;
vibro->depth = 0.5;
if ((n == 0) || !sscanf(argv[0], "%f", &vibro->speed) ||
((n == 2) && !sscanf(argv[1], "%f", &vibro->depth)))
fail("Usage: vibro speed [ depth ]");
if ((vibro->speed <= 0.001) || (vibro->speed > 30.0) ||
(vibro->depth < 0.0) || (vibro->depth > 1.0))
fail("Vibro: speed must be < 30.0, 0.0 < depth < 1.0");
}
/*
* Prepare processing.
*/
vibro_start(effp)
eff_t effp;
{
vibro_t vibro = (vibro_t) effp->priv;
vibro->length = effp->ininfo.rate / vibro->speed;
if (! (vibro->sinetab = (short*) malloc(vibro->length * sizeof(short))))
fail("Vibro: Cannot malloc %d bytes",
vibro->length * sizeof(short));
sine(vibro->sinetab, vibro->length, vibro->depth);
vibro->counter = 0;
}
/*
* Processed signed long samples from ibuf to obuf.
* Return number of samples processed.
*/
vibro_flow(effp, ibuf, obuf, isamp, osamp)
eff_t effp;
long *ibuf, *obuf;
int *isamp, *osamp;
{
vibro_t vibro = (vibro_t) effp->priv;
register counter, tablen;
int len, done;
register long mult;
register short *sinetab;
long l;
len = ((*isamp > *osamp) ? *osamp : *isamp);
sinetab = vibro->sinetab;
counter = vibro->counter;
tablen = vibro->length;
for(done = 0; done < len; done++) {
l = *ibuf++;
/* 24x8 gives 32-bit result */
*obuf++ = ((l / 256) * sinetab[counter++ % tablen]);
}
vibro->counter = counter;
/* processed all samples */
}
/*
* Do anything required when you stop reading samples.
* Don't close input file!
*/
vibro_stop(effp)
eff_t effp;
{
/* nothing to do */
}
/* This was very painful. We need a sine library. */
sine(buf, len, depth)
short *buf;
int len;
float depth;
{
int i;
int scale = depth * 128;
int base = (1.0 - depth) * 128;
double val;
for (i = 0; i < len; i++) {
val = sin((float)i/(float)len * 2.0 * M_PI);
buf[i] = (val + 1.0) * scale + base * 2;
}
/*
for (i = 0; i < len; i++)
fprintf(stderr, "%d\n", buf[i]);
*/
}